/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import me.zhengjie.config.exception.WeChatException;
import me.zhengjie.constant.ConstantUtils;
import me.zhengjie.modules.system.domain.CourseApplicants;
import me.zhengjie.modules.system.domain.CourseClassStudent;
import me.zhengjie.modules.system.domain.StudentBatchAddRequest;
import me.zhengjie.modules.web.enums.ApplicantsModifyFlagEnum;
import me.zhengjie.modules.web.service.mybatisplus.ICourseApplicantsPlusService;
import me.zhengjie.modules.web.service.mybatisplus.ICourseClassStudentPlusService;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.system.repository.CourseClassStudentRepository;
import me.zhengjie.modules.system.service.CourseClassStudentService;
import me.zhengjie.modules.system.service.dto.CourseClassStudentDto;
import me.zhengjie.modules.system.service.dto.CourseClassStudentQueryCriteria;
import me.zhengjie.modules.system.service.mapstruct.CourseClassStudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.SystemException;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author 王宇
* @date 2023-09-18
**/
@Service
@RequiredArgsConstructor
public class CourseClassStudentServiceImpl implements CourseClassStudentService {

    private final CourseClassStudentRepository courseClassStudentRepository;
    private final CourseClassStudentMapper courseClassStudentMapper;

    @Autowired
    private ICourseClassStudentPlusService studentPlusService;

    @Autowired
    private ICourseApplicantsPlusService applicantsPlusService;

    @Override
    public Map<String,Object> queryAll(CourseClassStudentQueryCriteria criteria, Pageable pageable){
        Page<CourseClassStudent> page = courseClassStudentRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(courseClassStudentMapper::toDto));
    }

    @Override
    public List<CourseClassStudentDto> queryAll(CourseClassStudentQueryCriteria criteria){
        return courseClassStudentMapper.toDto(courseClassStudentRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public CourseClassStudentDto findById(Long studentId) {
        CourseClassStudent courseClassStudent = courseClassStudentRepository.findById(studentId).orElseGet(CourseClassStudent::new);
        ValidationUtil.isNull(courseClassStudent.getStudentId(),"CourseClassStudent","studentId",studentId);
        return courseClassStudentMapper.toDto(courseClassStudent);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CourseClassStudentDto create(CourseClassStudent resources) {
        return courseClassStudentMapper.toDto(courseClassStudentRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(CourseClassStudent resources) {
        CourseClassStudent courseClassStudent = courseClassStudentRepository.findById(resources.getStudentId()).orElseGet(CourseClassStudent::new);
        ValidationUtil.isNull( courseClassStudent.getStudentId(),"CourseClassStudent","id",resources.getStudentId());
        String mobile = courseClassStudent.getPhoneNo();
        courseClassStudent.copy(resources);
        courseClassStudentRepository.save(courseClassStudent);

        //更新报名记录
        if (!mobile.equals(resources.getPhoneNo())){
            try {
                LambdaQueryWrapper<CourseApplicants> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(CourseApplicants::getCourseNo,resources.getCourseNo()).eq(CourseApplicants::getMobile,mobile);
                List<CourseApplicants> list = applicantsPlusService.list(wrapper);
                if (CollectionUtil.isNotEmpty(list)){
                    CourseApplicants applicants = list.get(0);
                    applicants.setMobile(resources.getPhoneNo());
                    //applicants.setModifyFlag(ApplicantsModifyFlagEnum.StudentModifyMobile.getFlag());
                    applicants.setModifyFlag(mobile);
                    applicantsPlusService.updateById(applicants);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long studentId : ids) {
            courseClassStudentRepository.deleteById(studentId);
        }
    }

    @Override
    public void download(List<CourseClassStudentDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (CourseClassStudentDto courseClassStudent : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("班级编号", courseClassStudent.getClassNo());
            map.put("创建时间", courseClassStudent.getCreateTime());
            map.put("创建人", courseClassStudent.getCreateby());
            map.put("更新时间", courseClassStudent.getUpdateTime());
            map.put("更新人", courseClassStudent.getUpdateby());
            map.put("课程编号", courseClassStudent.getCourseNo());
            map.put("用户名", courseClassStudent.getUserName());
            map.put("手机号", courseClassStudent.getPhoneNo());
            map.put("签到状态", courseClassStudent.getSignStatus());
            map.put("伙食费缴费状态", courseClassStudent.getMealsStatus());
            map.put("组号", courseClassStudent.getGroupNumber());
            map.put("听课时长", courseClassStudent.getLessonLength());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public boolean batchAdd(StudentBatchAddRequest request) {
        if (StringUtils.isAnyBlank(request.getClassNo(),request.getCourseNo()) || CollectionUtil.isEmpty(request.getStudentList())){
            throw new WeChatException("缺少参数");
        }
        /*CourseClassStudentQueryCriteria queryCriteria = new CourseClassStudentQueryCriteria();
        queryCriteria.setClassNo(request.getClassNo());
        queryCriteria.setCourseNo(request.getCourseNo());
        List<CourseClassStudentDto> studentDtoList = queryAll(queryCriteria);
        if (CollectionUtil.isNotEmpty(studentDtoList)){
            studentDtoList.parallelStream().forEach(s -> courseClassStudentRepository.deleteById(s.getStudentId()));
        }*/
        List<CourseClassStudent> list = new ArrayList<>();
        request.getStudentList().forEach(s -> {
            CourseClassStudent student = new CourseClassStudent();
            student.setClassNo(request.getClassNo());
            student.setCourseNo(request.getCourseNo());
            student.setGroupNumber(s.getGroupNumber());
            String mobile = StringUtils.defaultIfBlank(s.getPhoneNo(), s.getMobile());
            student.setPhoneNo(mobile);
            student.setUserName(s.getUserName());
            //student.setMealsStatus(s.getMealsStatus());
            student.setMealsStatus(ConstantUtils.Meals_Payed);
            student.setOpenId(s.getOpenId());
            student.setNickName(s.getNickname());
            student.setCreateTime(DateUtil.TimestampNow());
            student.setChannelSource(s.getChannelSource());
            list.add(student);
        });
        List<CourseClassStudent> respList = courseClassStudentRepository.saveAll(list);
        if (CollectionUtil.isEmpty(respList)){
            return false;
        }else {
            return true;
        }
    }

    @Override
    public List<String> groupNumbers(String classNo) {
        if (StringUtils.isBlank(classNo)){
            return null;
        }
        LambdaQueryWrapper<CourseClassStudent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseClassStudent::getClassNo,classNo);
        List<CourseClassStudent> list = studentPlusService.list(wrapper);
        if (CollectionUtil.isEmpty(list)){
            return null;
        }
        List<String> collect = list.stream().map(CourseClassStudent::getGroupNumber).distinct().collect(Collectors.toList());
        return collect;
    }
}